import urllib
import requests
import execjs
import csv
from tqdm import tqdm
import time
import random


class AirPollutionCrawler:

    def __init__(self, city="北京", data_type="DAY", province_name="北京"):
        self.url = 'https://www.zq12369.com/api/newzhenqiapi.php'
        self.headers = {
            'Accept': '*/*',
            'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,ja;q=0.6,ko;q=0.5',
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive',
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
            'Origin': 'https://www.zq12369.com',
            'Pragma': 'no-cache',
            'Referer': 'https://www.zq12369.com/',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
        }
        self.cookies = {
            # 对city参数进行url编码，采用用urllib模块的quote方法
            'city': urllib.parse.quote(city),
        }
        self.data = {
            'param': "QXNXclJtVnc5Mlg5S3Z2Zi9JVU1tbWxRRVRNWnlTMkFBMEVibGhHRjZMZ3NKMCtpQ2YrOXpnRGtnVFFQQlJOMlEwV1JVYVN1UmxZT05CaytEL3dMbkwzdjZJbDBRSDJ0MVlBUk9URUdENlRxSElIZVF6cG9HQkpUZzRYeWJGMXVlWkxNSmhWWUFTUTRsenRDQ0Vpb2FxalBZeVo1YXJ0WEQxQnZmSGMxeUVqeWMveHplNmw0aElaTllueDVYOWtSbmhXMjQydDVJSG4xYzlMaG9zaTQrM21QUDRBYk0yMGVQbUdQNjVlNGFPRXVSeXQ2U25vTFppN0M5TldJQ3BEWElXRFV3QytnbHljLzhPZjJRaStNZ09nYjNER2pOU1M0ME1VQjBvMWIrL0pXWWkwei9wTk01K3Yrekw5RDJEYkRvdHFLTlhUSE8vMjQ3ZkdUSFNTRXRRT2p5c2N1SVRXb3d6UWREWExrMVA3QmNCSWpjRDlCYy8yVENmK3pkTzA1THJqNXp2bEZwWXZpb0tBVkhRL1Y0dG5CMnI1RDZmM3hkNURrMWdHd041WElyZ0VmK2pXcDljaU9HaEF3Q3BQamEyazZoV25Kandubmprd2V6U1JaR1doaUpDb0tyemV0LzdIcjM0Q24wRW5lS1gyZnpIbHh0OS96aDZ5aHpta2ZmQWpnaEJQY1lZalp1enB2K0pSa1pGNmZzK3hxWG1DMmg2MkV2NWZCcnlFUEFoUlZCTkpGZ2hvdUY5andIVVJEQndic2k3cnpTQlZqMGNsUUpZRTA1bXlaSzlSV29TU1BMQmJaOEdNU0ptcWh0QTdFYng0by84Qmh0dVh6dThWNjFXK09PaVJtdE5lT1UyQkJjQUJkRmJmUE9URkcvRnJteEZFSEVuOHdaL2RSUTI4dzVYRFNhbERwaCtrbVlTNE1TbUpYOGRsUXMySFBiS01nOE5TNXdiVEk4RzQyV0haSFNsc2F4R1I5LzdVM1ZySmRxbXdyaHQzanNuQ2NPREZjTW0vUlBGelpvY0ZUMTlDZ0pkVUp0UTFpRGJ2WFFURloxZ3RmRU1OYVluelFUZjAxNXkwODN0UWpuckZWdmozSHBnaXBQeGtTVUFvMW44amdrTkI2ZDJKUkdQRGZhSE1COU9lS1JhZStOcWc9",
        }
        self.obj = {
            "city": city,
            "type": data_type,
            "startTime": "2019-01-01 00:00:00",
            "endTime": "2023-12-31 23:00:00"
        }
        self.province_name = province_name
        self.response_data = ""

    def get_data(self):
        """
        try:
            # 先得到加密的param
            js_ctx = execjs.compile(open("request_encrypt.js", "r", encoding="utf-8").read())
            # 调用js代码中的mygetParam方法，传入obj参数
            param = js_ctx.call("mygetParam", self.obj)
            self.data = {
                'param': param
            }
            response = requests.post(
                url=self.url,
                cookies=self.cookies,
                headers=self.headers,
                data=self.data
            )
            print(response.text)
            self.response_data = response.text
        except Exception as e:
            print(e)
        """
        # 先得到加密的param
        js_ctx = execjs.compile(open("request_encrypt.js", "r", encoding="utf-8").read())
        # 调用js代码中的mygetParam方法，传入obj参数
        param = js_ctx.call("mygetParam", self.obj)
        self.data = {
            'param': param
        }
        # print(param)
        response = requests.post(
            url=self.url,
            cookies=self.cookies,
            headers=self.headers,
            data=self.data
        )
        # print(response)
        # print(response.text)
        print(f"获取{self.province_name}空气质量数据成功！")
        self.response_data = response.text

    def parse_data(self):
        js_ctx = execjs.compile(open("response_decrypt.js", "r", encoding="utf-8").read())
        air_data = js_ctx.call("getData", self.response_data)
        print(f"解析{self.province_name}空气质量数据成功！")
        for row in air_data['rows']:
            row['province'] = self.province_name
            row['city'] = self.obj['city']

        self.save_data(air_data['rows'])

    def save_data(self, rows):
        with open(f"../data/{self.province_name}.csv", "a", encoding="utf-8", newline="") as f:
            fieldnames = [
                "province", "city", "time",
                "aqi", "pm2_5", "pm10", "so2", "no2", "co", "o3",
                "complexindex", "rank", "primary_pollutant",
                "temp", "humi", "windlevel", "winddirection", "weather"
            ]
            csv_writer = csv.DictWriter(f, fieldnames=fieldnames)
            csv_writer.writerows(rows)
            print(f"保存{self.province_name}空气质量数据成功！")

    def run(self):
        self.get_data()
        self.parse_data()


def get_province():
    province_list = [
        {'Id': 1, 'ProvinceCode': 110000, 'ProvinceName': '北京', 'ProvinceJC': 'BJ', 'CapitalCity': '北京'},
        {'Id': 2, 'ProvinceCode': 120000, 'ProvinceName': '天津', 'ProvinceJC': 'TJ', 'CapitalCity': '天津'},
        {'Id': 3, 'ProvinceCode': 130000, 'ProvinceName': '河北', 'ProvinceJC': 'HB', 'CapitalCity': '石家庄'},
        {'Id': 4, 'ProvinceCode': 140000, 'ProvinceName': '山西', 'ProvinceJC': 'SX', 'CapitalCity': '太原'},
        {'Id': 5, 'ProvinceCode': 150000, 'ProvinceName': '内蒙古', 'ProvinceJC': 'NMG', 'CapitalCity': '呼和浩特'},
        {'Id': 6, 'ProvinceCode': 210000, 'ProvinceName': '辽宁', 'ProvinceJC': 'LN', 'CapitalCity': '沈阳'},
        {'Id': 7, 'ProvinceCode': 220000, 'ProvinceName': '吉林', 'ProvinceJC': 'JL', 'CapitalCity': '长春'},
        {'Id': 8, 'ProvinceCode': 230000, 'ProvinceName': '黑龙江', 'ProvinceJC': 'HLJ', 'CapitalCity': '哈尔滨'},
        {'Id': 9, 'ProvinceCode': 310000, 'ProvinceName': '上海', 'ProvinceJC': 'SH', 'CapitalCity': '上海'},
        {'Id': 10, 'ProvinceCode': 320000, 'ProvinceName': '江苏', 'ProvinceJC': 'JS', 'CapitalCity': '南京'},
        {'Id': 11, 'ProvinceCode': 330000, 'ProvinceName': '浙江', 'ProvinceJC': 'ZJ', 'CapitalCity': '杭州'},
        {'Id': 12, 'ProvinceCode': 340000, 'ProvinceName': '安徽', 'ProvinceJC': 'AH', 'CapitalCity': '合肥'},
        {'Id': 13, 'ProvinceCode': 350000, 'ProvinceName': '福建', 'ProvinceJC': 'FJ', 'CapitalCity': '福州'},
        {'Id': 14, 'ProvinceCode': 360000, 'ProvinceName': '江西', 'ProvinceJC': 'JX', 'CapitalCity': '南昌'},
        {'Id': 15, 'ProvinceCode': 370000, 'ProvinceName': '山东', 'ProvinceJC': 'SD', 'CapitalCity': '济南'},
        {'Id': 16, 'ProvinceCode': 410000, 'ProvinceName': '河南', 'ProvinceJC': 'HN', 'CapitalCity': '郑州'},
        {'Id': 17, 'ProvinceCode': 420000, 'ProvinceName': '湖北', 'ProvinceJC': 'HB', 'CapitalCity': '武汉'},
        {'Id': 18, 'ProvinceCode': 430000, 'ProvinceName': '湖南', 'ProvinceJC': 'HN', 'CapitalCity': '长沙'},
        {'Id': 19, 'ProvinceCode': 440000, 'ProvinceName': '广东', 'ProvinceJC': 'GD', 'CapitalCity': '广州'},
        {'Id': 20, 'ProvinceCode': 450000, 'ProvinceName': '广西', 'ProvinceJC': 'GX', 'CapitalCity': '南宁'},
        {'Id': 21, 'ProvinceCode': 460000, 'ProvinceName': '海南', 'ProvinceJC': 'HI', 'CapitalCity': '海口'},
        {'Id': 22, 'ProvinceCode': 500000, 'ProvinceName': '重庆', 'ProvinceJC': 'CQ', 'CapitalCity': '重庆'},
        {'Id': 23, 'ProvinceCode': 510000, 'ProvinceName': '四川', 'ProvinceJC': 'SC', 'CapitalCity': '成都'},
        {'Id': 24, 'ProvinceCode': 520000, 'ProvinceName': '贵州', 'ProvinceJC': 'GZ', 'CapitalCity': '贵阳'},
        {'Id': 25, 'ProvinceCode': 530000, 'ProvinceName': '云南', 'ProvinceJC': 'YN', 'CapitalCity': '昆明'},
        {'Id': 26, 'ProvinceCode': 540000, 'ProvinceName': '西藏', 'ProvinceJC': 'XZ', 'CapitalCity': '拉萨'},
        {'Id': 27, 'ProvinceCode': 610000, 'ProvinceName': '陕西', 'ProvinceJC': 'SN', 'CapitalCity': '西安'},
        {'Id': 28, 'ProvinceCode': 620000, 'ProvinceName': '甘肃', 'ProvinceJC': 'GS', 'CapitalCity': '兰州'},
        {'Id': 29, 'ProvinceCode': 630000, 'ProvinceName': '青海', 'ProvinceJC': 'QH', 'CapitalCity': '西宁'},
        {'Id': 30, 'ProvinceCode': 640000, 'ProvinceName': '宁夏', 'ProvinceJC': 'NX', 'CapitalCity': '银川'},
        {'Id': 31, 'ProvinceCode': 650000, 'ProvinceName': '新疆', 'ProvinceJC': 'XJ', 'CapitalCity': '乌鲁木齐'},
        {'Id': 32, 'ProvinceCode': 710000, 'ProvinceName': '台湾', 'ProvinceJC': 'TW', 'CapitalCity': '台北'},
        {'Id': 33, 'ProvinceCode': 810000, 'ProvinceName': '香港', 'ProvinceJC': 'HK', 'CapitalCity': '香港'},
        {'Id': 34, 'ProvinceCode': 820000, 'ProvinceName': '澳门', 'ProvinceJC': 'MO', 'CapitalCity': '澳门'}
    ]
    return province_list


if __name__ == '__main__':
    province_list = get_province()[:31]
    for province in tqdm(province_list, desc="省份省会"):
        # 创建csv文件
        with open(f"../data/{province['ProvinceName']}.csv", "a", encoding="utf-8", newline="") as f:
            fieldnames = [
                "province", "city", "time",
                "aqi", "pm2_5", "pm10", "so2", "no2", "co", "o3",
                "complexindex", "rank", "primary_pollutant",
                "temp", "humi", "windlevel", "winddirection", "weather"
            ]
            csv_writer = csv.DictWriter(f, fieldnames=fieldnames)
            csv_writer.writeheader()
        # 执行爬取
        base_city = province['CapitalCity']
        base_province = province['ProvinceName']
        print(f"{base_province} {base_city}")
        # d_type = "HOUR"
        d_type = "DAY"
        crawler = AirPollutionCrawler(base_city, d_type, base_province)
        crawler.run()
        # break
        time.sleep(random.uniform(5, 15))
